/**
 * XappTool Web SDK
 * 免邀请安装归因 SDK
 * 类似 xinstall/openinstall/sharetrace 功能
 * @version 1.0.0
 */

(function(global) {
  'use strict';

  /**
   * 工具函数
   */
  const Utils = {
    // 生成唯一ID
    generateUUID() {
      return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function(c) {
        const r = Math.random() * 16 | 0;
        const v = c === 'x' ? r : (r & 0x3 | 0x8);
        return v.toString(16);
      });
    },

    // 设备指纹生成
    generateDeviceFingerprint() {
      const canvas = document.createElement('canvas');
      const ctx = canvas.getContext('2d');
      
      // Canvas 指纹
      ctx.textBaseline = 'top';
      ctx.font = '14px Arial';
      ctx.fillStyle = '#f60';
      ctx.fillRect(125, 1, 62, 20);
      ctx.fillStyle = '#069';
      ctx.fillText('Canvas fingerprint 🎨', 2, 15);
      
      const canvasData = canvas.toDataURL();
      
      // 收集设备信息
      const info = {
        userAgent: navigator.userAgent,
        language: navigator.language,
        languages: navigator.languages ? navigator.languages.join(',') : '',
        platform: navigator.platform,
        cookieEnabled: navigator.cookieEnabled,
        doNotTrack: navigator.doNotTrack,
        screenResolution: `${screen.width}x${screen.height}`,
        screenColorDepth: screen.colorDepth,
        timezone: Intl.DateTimeFormat().resolvedOptions().timeZone,
        canvas: canvasData,
        webgl: this.getWebGLFingerprint(),
        audio: this.getAudioFingerprint(),
        fonts: this.getFontsFingerprint(),
        plugins: this.getPluginsFingerprint(),
        localStorage: !!window.localStorage,
        sessionStorage: !!window.sessionStorage,
        indexedDB: !!window.indexedDB,
        openDatabase: !!window.openDatabase,
        cpuClass: navigator.cpuClass || '',
        hardwareConcurrency: navigator.hardwareConcurrency || 0,
        maxTouchPoints: navigator.maxTouchPoints || 0,
        touchSupport: 'ontouchstart' in window,
        deviceMemory: navigator.deviceMemory || 0
      };
      
      // 生成哈希
      const fingerprintString = JSON.stringify(info);
      return this.sha256(fingerprintString);
    },

    // WebGL 指纹
    getWebGLFingerprint() {
      try {
        const canvas = document.createElement('canvas');
        const gl = canvas.getContext('webgl') || canvas.getContext('experimental-webgl');
        if (!gl) return '';
        
        const debugInfo = gl.getExtension('WEBGL_debug_renderer_info');
        const vendor = debugInfo ? gl.getParameter(debugInfo.UNMASKED_VENDOR_WEBGL) : '';
        const renderer = debugInfo ? gl.getParameter(debugInfo.UNMASKED_RENDERER_WEBGL) : '';
        
        return `${vendor}~${renderer}`;
      } catch (e) {
        return '';
      }
    },

    // 音频指纹
    getAudioFingerprint() {
      try {
        const audioContext = new (window.AudioContext || window.webkitAudioContext)();
        const oscillator = audioContext.createOscillator();
        const analyser = audioContext.createAnalyser();
        const gainNode = audioContext.createGain();
        const scriptProcessor = audioContext.createScriptProcessor(4096, 1, 1);
        
        oscillator.type = 'triangle';
        oscillator.frequency.setValueAtTime(10000, audioContext.currentTime);
        
        gainNode.gain.setValueAtTime(0, audioContext.currentTime);
        oscillator.connect(analyser);
        analyser.connect(scriptProcessor);
        scriptProcessor.connect(gainNode);
        gainNode.connect(audioContext.destination);
        
        return new Promise((resolve) => {
          scriptProcessor.onaudioprocess = function(bins) {
            const data = bins.inputBuffer.getChannelData(0);
            let sum = 0;
            for (let i = 0; i < data.length; i++) {
              sum += Math.abs(data[i]);
            }
            resolve(sum.toString());
          };
          
          oscillator.start(0);
          setTimeout(() => {
            oscillator.stop();
            audioContext.close();
            resolve('');
          }, 100);
        });
      } catch (e) {
        return Promise.resolve('');
      }
    },

    // 字体指纹
    getFontsFingerprint() {
      const fonts = [
        'Arial', 'Arial Black', 'Arial Narrow', 'Arial Rounded MT Bold',
        'Book Antiqua', 'Bookman Old Style', 'Calibri', 'Cambria',
        'Cambria Math', 'Century', 'Century Gothic', 'Century Schoolbook',
        'Comic Sans MS', 'Consolas', 'Courier', 'Courier New',
        'Garamond', 'Georgia', 'Helvetica', 'Impact', 'Lucida Console',
        'Lucida Sans Unicode', 'Microsoft Sans Serif', 'Monotype Corsiva',
        'MS Gothic', 'MS PGothic', 'MS Reference Sans Serif', 'MS Sans Serif',
        'MS Serif', 'Palatino Linotype', 'Segoe Print', 'Segoe Script',
        'Segoe UI', 'Segoe UI Light', 'Segoe UI Semibold', 'Segoe UI Symbol',
        'Tahoma', 'Times', 'Times New Roman', 'Trebuchet MS', 'Verdana',
        'Wingdings', 'Wingdings 2', 'Wingdings 3'
      ];
      
      const availableFonts = [];
      const testString = 'mmmmmmmmmmlli';
      const testSize = '72px';
      const h = document.getElementsByTagName('body')[0];
      
      const baseFonts = ['monospace', 'sans-serif', 'serif'];
      const testElement = document.createElement('span');
      testElement.style.position = 'absolute';
      testElement.style.left = '-9999px';
      testElement.style.fontSize = testSize;
      testElement.innerHTML = testString;
      
      for (const baseFont of baseFonts) {
        testElement.style.fontFamily = baseFont;
        h.appendChild(testElement);
        const defaultWidth = testElement.offsetWidth;
        const defaultHeight = testElement.offsetHeight;
        h.removeChild(testElement);
        
        for (const font of fonts) {
          testElement.style.fontFamily = font + ',' + baseFont;
          h.appendChild(testElement);
          const width = testElement.offsetWidth;
          const height = testElement.offsetHeight;
          h.removeChild(testElement);
          
          if (width !== defaultWidth || height !== defaultHeight) {
            availableFonts.push(font);
          }
        }
      }
      
      return availableFonts.join(',');
    },

    // 插件指纹
    getPluginsFingerprint() {
      if (!navigator.plugins || navigator.plugins.length === 0) {
        return '';
      }
      
      const plugins = [];
      for (let i = 0; i < navigator.plugins.length; i++) {
        const plugin = navigator.plugins[i];
        const pluginStr = [];
        for (let j = 0; j < plugin.length; j++) {
          pluginStr.push(plugin[j].type + '~' + plugin[j].suffixes);
        }
        plugins.push(plugin.name + '~' + plugin.description + '~' + pluginStr.join(','));
      }
      
      return plugins.join(';');
    },

    // 哈希函数
    hashCode(str) {
      let hash = 0;
      if (str.length === 0) return hash;
      for (let i = 0; i < str.length; i++) {
        const char = str.charCodeAt(i);
        hash = ((hash << 5) - hash) + char;
        hash = hash & hash; // Convert to 32bit integer
      }
      return Math.abs(hash).toString(36);
    },

    // 检测模拟器
    detectEmulator() {
      const userAgent = navigator.userAgent.toLowerCase();
      const emulatorKeywords = [
        'bluestacks', 'nox', 'memu', 'koplayer', 'droid4x',
        'andy', 'genymotion', 'windroy', 'youwave', 'leapdroid'
      ];
      
      return emulatorKeywords.some(keyword => userAgent.includes(keyword));
    },

    // 检测VPN/代理
    async detectVPN() {
      try {
        // 检查WebRTC IP泄露
        const rtcPeerConnection = window.RTCPeerConnection || window.webkitRTCPeerConnection;
        if (rtcPeerConnection) {
          const pc = new rtcPeerConnection({
            iceServers: [{urls: 'stun:stun.l.google.com:19302'}]
          });
          
          return new Promise((resolve) => {
            pc.onicecandidate = (event) => {
              if (event.candidate) {
                const ip = event.candidate.candidate.split(' ')[4];
                if (ip && !ip.startsWith('192.168.') && !ip.startsWith('10.') && !ip.startsWith('172.')) {
                  resolve(true);
                }
              }
            };
            
            pc.createDataChannel('');
            pc.createOffer().then(offer => pc.setLocalDescription(offer));
            
            setTimeout(() => {
              pc.close();
              resolve(false);
            }, 1000);
          });
        }
      } catch (e) {
        return false;
      }
      
      return false;
    },

    // 检测机器人
    detectBot() {
      const userAgent = navigator.userAgent.toLowerCase();
      const botKeywords = [
        'bot', 'crawler', 'spider', 'scraper', 'automation',
        'selenium', 'phantomjs', 'puppeteer', 'playwright',
        'headless', 'webdriver', 'geckodriver', 'chromedriver'
      ];
      
      return botKeywords.some(keyword => userAgent.includes(keyword));
    },

    // 检测无头浏览器
    detectHeadless() {
      return (
        navigator.webdriver ||
        !navigator.plugins.length ||
        !navigator.languages ||
        navigator.languages.length === 0 ||
        screen.width === 0 ||
        screen.height === 0 ||
        !navigator.mimeTypes.length ||
        window.outerHeight === 0 ||
        window.outerWidth === 0
      );
    },

    // 获取IP地址
    async getIPAddress() {
      try {
        const response = await fetch('https://api.ipify.org?format=json');
        const data = await response.json();
        return data.ip;
      } catch (e) {
        return '';
      }
    },

    // 获取地理位置
    async getGeolocation() {
      return new Promise((resolve) => {
        if (!navigator.geolocation) {
          resolve({});
          return;
        }
        
        navigator.geolocation.getCurrentPosition(
          (position) => {
            resolve({
              latitude: position.coords.latitude,
              longitude: position.coords.longitude,
              accuracy: position.coords.accuracy
            });
          },
          () => {
            resolve({});
          },
          { timeout: 5000 }
        );
      });
    },

    // 防抖函数
    debounce(func, wait) {
      let timeout;
      return function executedFunction(...args) {
        const later = () => {
          clearTimeout(timeout);
          func(...args);
        };
        clearTimeout(timeout);
        timeout = setTimeout(later, wait);
      };
    },

    // 节流函数
    throttle(func, limit) {
      let inThrottle;
      return function() {
        const args = arguments;
        const context = this;
        if (!inThrottle) {
          func.apply(context, args);
          inThrottle = true;
          setTimeout(() => inThrottle = false, limit);
        }
      };
    },

    // 深度克隆
    deepClone(obj) {
      if (obj === null || typeof obj !== 'object') return obj;
      if (obj instanceof Date) return new Date(obj.getTime());
      if (obj instanceof Array) return obj.map(item => this.deepClone(item));
      if (typeof obj === 'object') {
        const cloned = {};
        for (const key in obj) {
          if (obj.hasOwnProperty(key)) {
            cloned[key] = this.deepClone(obj[key]);
          }
        }
        return cloned;
      }
    },

    // 压缩数据
    compress(data) {
      try {
        return btoa(encodeURIComponent(JSON.stringify(data)));
      } catch (e) {
        return data;
      }
    },

    // 解压缩数据
    decompress(data) {
      try {
        return JSON.parse(decodeURIComponent(atob(data)));
      } catch (e) {
        return data;
      }
    }
  };

  /**
   * XappTool SDK 主类
   */
  class XappTool {
    constructor(options = {}) {
      this.config = {
        apiKey: '',
        apiUrl: 'https://api.xapptool.cn',
        timeout: 5000,
        debug: false,
        environment: 'production',
        fingerprint: {
          include: [],
          exclude: [],
          customData: {},
          privacyMode: false
        },
        performance: {
          enableCache: true,
          cacheTimeout: 3600000,
          enableCompression: true,
          batchRequests: false,
          batchSize: 10,
          batchInterval: 5000
        },
        privacy: {
          gdpr: { enabled: false },
          ccpa: { enabled: false },
          cookieConsent: { enabled: false }
        },
        cors: {
          enabled: false,
          proxy: '',
          jsonp: false
        },
        ...options
      };
      
      this.isInitialized = false;
      this.deviceFingerprint = '';
      this.sessionId = Utils.generateUUID();
      this.cache = new Map();
      this.requestQueue = [];
      this.eventListeners = {};
      
      this.initFingerprint();
    }

    /**
     * 初始化 SDK
     */
    async init(options = {}) {
      try {
        this.config = { ...this.config, ...options };
        
        if (!this.config.apiKey) {
          throw new Error('API Key is required');
        }
        
        this.log('Initializing XappTool SDK...');
        
        // 生成设备指纹
        this.deviceFingerprint = await this.generateFingerprint();
        
        // 检查隐私合规
        if (this.config.privacy.gdpr.enabled || this.config.privacy.ccpa.enabled) {
          await this.checkPrivacyCompliance();
        }
        
        // 检查浏览器兼容性
        this.checkBrowserCompatibility();
        
        // 启动性能监控
        if (this.config.performance.enableCache) {
          this.startCacheCleanup();
        }
        
        // 启动批量请求处理
        if (this.config.performance.batchRequests) {
          this.startBatchProcessor();
        }
        
        this.isInitialized = true;
        this.emit('ready', { deviceFingerprint: this.deviceFingerprint });
        
        this.log('XappTool SDK initialized successfully');
        return { success: true, deviceFingerprint: this.deviceFingerprint };
        
      } catch (error) {
        this.log('SDK initialization failed:', error);
        this.emit('error', error);
        throw error;
      }
    }

    /**
     * 生成设备指纹
     */
    async generateFingerprint() {
      try {
        // 检查缓存
        const cacheKey = 'device_fingerprint';
        if (this.config.performance.enableCache) {
          const cached = this.getCache(cacheKey);
          if (cached) return cached;
        }
        
        let fingerprint = await Utils.generateDeviceFingerprint();
        
        // 添加自定义数据
        if (this.config.fingerprint.customData) {
          const customString = JSON.stringify(this.config.fingerprint.customData);
          fingerprint += Utils.hashCode(customString);
        }
        
        // 缓存指纹
        if (this.config.performance.enableCache) {
          this.setCache(cacheKey, fingerprint, this.config.performance.cacheTimeout);
        }
        
        return fingerprint;
      } catch (error) {
        this.log('Fingerprint generation failed:', error);
        return Utils.generateUUID(); // 回退方案
      }
    }

    /**
     * 获取安装参数
     */
    async getInstallParams() {
      if (!this.isInitialized) {
        throw new Error('SDK not initialized');
      }
      
      try {
        // 检查缓存
        const cacheKey = 'install_params_' + this.deviceFingerprint;
        if (this.config.performance.enableCache) {
          const cached = this.getCache(cacheKey);
          if (cached) return cached;
        }
        
        // 获取当前URL参数
        const urlParams = this.getUrlParams();
        
        // 构建请求数据
        const requestData = {
          apiKey: this.config.apiKey,
          deviceFingerprint: this.deviceFingerprint,
          sessionId: this.sessionId,
          url: window.location.href,
          referrer: document.referrer,
          userAgent: navigator.userAgent,
          timestamp: Date.now(),
          urlParams: urlParams,
          fingerprint: this.deviceFingerprint,
          ip: await Utils.getIPAddress(),
          geolocation: await Utils.getGeolocation()
        };
        
        // 发送归因请求
        const response = await this.request('/api/v1/attribution', requestData);
        
        const installParams = {
          inviter: response.data.inviter || null,
          channel: response.data.channel || null,
          params: response.data.params || {},
          utm: response.data.utm || {},
          attributionType: response.data.attributionType || 'organic',
          method: response.data.attributionType || 'organic',
          confidence: response.data.confidence || 0,
          timestamp: response.data.timestamp || Date.now()
        };
        
        // 缓存结果
        if (this.config.performance.enableCache) {
          this.setCache(cacheKey, installParams, this.config.performance.cacheTimeout);
        }
        
        return installParams;
        
      } catch (error) {
        this.log('Failed to get install params:', error);
        
        // 返回默认参数
        return {
          inviter: null,
          channel: null,
          params: {},
          utm: this.getUrlParams(),
          attributionType: 'organic',
          method: 'organic',
          confidence: 0,
          timestamp: Date.now()
        };
      }
    }

    /**
     * 生成邀请链接
     */
    async generateInvitationLink(options = {}) {
      if (!this.isInitialized) {
        throw new Error('SDK not initialized');
      }
      
      try {
        const {
          userId = '',
          code = '',
          channel = 'direct',
          params = {},
          expireDays = 7
        } = options;
        
        const requestData = {
          apiKey: this.config.apiKey,
          userId: userId,
          code: code || Utils.generateUUID().substr(0, 8),
          channel: channel,
          params: params,
          expireDays: expireDays,
          deviceFingerprint: this.deviceFingerprint
        };
        
        const response = await this.request('/api/v1/invitation-link', requestData);
        
        return response.data.invitationLink;
        
      } catch (error) {
        this.log('Failed to generate invitation link:', error);
        
        // 生成默认链接
        const baseUrl = window.location.origin + window.location.pathname;
        const params = new URLSearchParams({
          inviter: options.userId || '',
          code: options.code || Utils.generateUUID().substr(0, 8),
          channel: options.channel || 'direct',
          ...options.params
        });
        
        return baseUrl + '?' + params.toString();
      }
    }

    /**
     * 获取设备指纹
     */
    getDeviceFingerprint() {
      return this.deviceFingerprint;
    }

    /**
     * 获取设备信息
     */
    async getDeviceInfo() {
      return {
        userAgent: navigator.userAgent,
        language: navigator.language,
        platform: navigator.platform,
        cookieEnabled: navigator.cookieEnabled,
        doNotTrack: navigator.doNotTrack,
        screenResolution: `${screen.width}x${screen.height}`,
        screenColorDepth: screen.colorDepth,
        timezone: Intl.DateTimeFormat().resolvedOptions().timeZone,
        fingerprint: this.deviceFingerprint,
        sessionId: this.sessionId,
        isEmulator: Utils.detectEmulator(),
        isBot: Utils.detectBot(),
        isHeadless: Utils.detectHeadless(),
        isMobile: this.isMobile(),
        browser: this.getBrowserInfo(),
        os: this.getOSInfo(),
        ip: await Utils.getIPAddress(),
        geolocation: await Utils.getGeolocation()
      };
    }

    /**
     * 反作弊检测
     */
    async checkAntiFraud() {
      const results = {
        isSuspicious: false,
        reasons: [],
        isEmulator: await Utils.detectEmulator(),
        isUsingVPN: await Utils.detectVPN(),
        isBot: Utils.detectBot(),
        isHeadless: Utils.detectHeadless(),
        hasFakeUserAgent: this.hasFakeUserAgent(),
        pluginsAnomaly: this.checkPluginsAnomaly(),
        webDriverDetected: navigator.webdriver || false,
        suspiciousBehavior: this.detectSuspiciousBehavior()
      };
      
      // 综合判断
      if (results.isEmulator) {
        results.isSuspicious = true;
        results.reasons.push('Detected emulator environment');
      }
      
      if (results.isUsingVPN) {
        results.isSuspicious = true;
        results.reasons.push('Detected VPN/Proxy usage');
      }
      
      if (results.isBot) {
        results.isSuspicious = true;
        results.reasons.push('Detected bot behavior');
      }
      
      if (results.isHeadless) {
        results.isSuspicious = true;
        results.reasons.push('Detected headless browser');
      }
      
      if (results.webDriverDetected) {
        results.isSuspicious = true;
        results.reasons.push('Detected WebDriver');
      }
      
      return results;
    }

    /**
     * 获取渠道统计
     */
    async getChannelStats(options = {}) {
      try {
        const {
          startDate = new Date(Date.now() - 30 * 24 * 60 * 60 * 1000).toISOString(),
          endDate = new Date().toISOString(),
          channel = ''
        } = options;
        
        const requestData = {
          apiKey: this.config.apiKey,
          startDate: startDate,
          endDate: endDate,
          channel: channel,
          deviceFingerprint: this.deviceFingerprint
        };
        
        const response = await this.request('/api/v1/channel-stats', requestData);
        
        return response.data;
        
      } catch (error) {
        this.log('Failed to get channel stats:', error);
        return {
          totalInstalls: 0,
          channelStats: [],
          conversionRate: 0
        };
      }
    }

    /**
     * 发送请求
     */
    async request(endpoint, data = {}) {
      try {
        const url = this.config.cors.enabled && this.config.cors.proxy 
          ? this.config.cors.proxy + endpoint 
          : this.config.apiUrl + endpoint;
        
        // 压缩数据
        let requestData = data;
        if (this.config.performance.enableCompression) {
          requestData = { compressed: Utils.compress(data) };
        }
        
        const options = {
          method: 'POST',
          headers: {
            'Content-Type': 'application/json',
            'X-API-Key': this.config.apiKey,
            'X-Session-ID': this.sessionId,
            'X-Fingerprint': this.deviceFingerprint,
            'X-SDK-Version': '1.0.0'
          },
          body: JSON.stringify(requestData),
          signal: AbortSignal.timeout(this.config.timeout)
        };
        
        const response = await fetch(url, options);
        
        if (!response.ok) {
          throw new Error(`HTTP ${response.status}: ${response.statusText}`);
        }
        
        const result = await response.json();
        
        if (result.code !== 0) {
          throw new Error(result.message || 'Request failed');
        }
        
        return result;
        
      } catch (error) {
        if (error.name === 'AbortError') {
          throw new Error('Request timeout');
        }
        
        this.log('Request failed:', error);
        throw error;
      }
    }

    /**
     * 获取URL参数
     */
    getUrlParams() {
      const params = {};
      const searchParams = new URLSearchParams(window.location.search);
      
      for (const [key, value] of searchParams) {
        params[key] = value;
      }
      
      return params;
    }

    /**
     * 缓存操作
     */
    getCache(key) {
      try {
        const cached = this.cache.get(key);
        if (cached && cached.expires > Date.now()) {
          return cached.data;
        }
        this.cache.delete(key);
        return null;
      } catch (e) {
        return null;
      }
    }

    setCache(key, data, timeout = 3600000) {
      try {
        this.cache.set(key, {
          data: data,
          expires: Date.now() + timeout
        });
      } catch (e) {
        // 忽略缓存错误
      }
    }

    /**
     * 事件监听
     */
    on(event, callback) {
      if (!this.eventListeners[event]) {
        this.eventListeners[event] = [];
      }
      this.eventListeners[event].push(callback);
    }

    off(event, callback) {
      if (this.eventListeners[event]) {
        this.eventListeners[event] = this.eventListeners[event].filter(cb => cb !== callback);
      }
    }

    emit(event, data) {
      if (this.eventListeners[event]) {
        this.eventListeners[event].forEach(callback => {
          try {
            callback(data);
          } catch (e) {
            this.log('Event callback error:', e);
          }
        });
      }
    }

    /**
     * 日志记录
     */
    log(...args) {
      if (this.config.debug) {
        console.log('[XappTool]', ...args);
      }
    }

    /**
     * 其他辅助方法
     */
    isMobile() {
      return /Android|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/i.test(navigator.userAgent);
    }

    getBrowserInfo() {
      const ua = navigator.userAgent;
      let browser = 'Unknown';
      let version = 'Unknown';
      
      if (ua.indexOf('Chrome') > -1) {
        browser = 'Chrome';
        version = ua.match(/Chrome\/(\d+\.\d+)/)?.[1] || 'Unknown';
      } else if (ua.indexOf('Firefox') > -1) {
        browser = 'Firefox';
        version = ua.match(/Firefox\/(\d+\.\d+)/)?.[1] || 'Unknown';
      } else if (ua.indexOf('Safari') > -1) {
        browser = 'Safari';
        version = ua.match(/Version\/(\d+\.\d+)/)?.[1] || 'Unknown';
      } else if (ua.indexOf('Edge') > -1) {
        browser = 'Edge';
        version = ua.match(/Edge\/(\d+\.\d+)/)?.[1] || 'Unknown';
      }
      
      return { browser, version };
    }

    getOSInfo() {
      const ua = navigator.userAgent;
      let os = 'Unknown';
      let version = 'Unknown';
      
      if (ua.indexOf('Windows NT') > -1) {
        os = 'Windows';
        version = ua.match(/Windows NT (\d+\.\d+)/)?.[1] || 'Unknown';
      } else if (ua.indexOf('Mac OS X') > -1) {
        os = 'macOS';
        version = ua.match(/Mac OS X (\d+[_\.]\d+)/)?.[1] || 'Unknown';
      } else if (ua.indexOf('Android') > -1) {
        os = 'Android';
        version = ua.match(/Android (\d+\.\d+)/)?.[1] || 'Unknown';
      } else if (ua.indexOf('iOS') > -1 || ua.indexOf('iPhone') > -1 || ua.indexOf('iPad') > -1) {
        os = 'iOS';
        version = ua.match(/OS (\d+[_\.]\d+)/)?.[1] || 'Unknown';
      }
      
      return { os, version };
    }

    hasFakeUserAgent() {
      const ua = navigator.userAgent.toLowerCase();
      const fakePatterns = [
        /\d{10,}/, // 过长的数字序列
        /[a-z]{20,}/, // 过长的字母序列
        /(bot|crawler|spider|scraper)/, // 机器人关键词
        /(selenium|phantomjs|puppeteer|playwright)/ // 自动化工具
      ];
      
      return fakePatterns.some(pattern => pattern.test(ua));
    }

    checkPluginsAnomaly() {
      if (!navigator.plugins || navigator.plugins.length === 0) {
        return true; // 没有插件可能是无头浏览器
      }
      
      // 检查插件数量异常
      if (navigator.plugins.length > 20) {
        return true;
      }
      
      return false;
    }

    detectSuspiciousBehavior() {
      let suspicious = false;
      const reasons = [];
      
      // 检查是否禁用了图片/样式
      if (!document.images || document.images.length === 0) {
        suspicious = true;
        reasons.push('No images detected');
      }
      
      // 检查是否禁用了JavaScript
      if (typeof window.callPhantom !== 'undefined' || 
          typeof window._phantom !== 'undefined' ||
          typeof window.__phantomas !== 'undefined') {
        suspicious = true;
        reasons.push('PhantomJS detected');
      }
      
      return { suspicious, reasons };
    }

    checkBrowserCompatibility() {
      const compatibility = {
        isSupported: true,
        reason: '',
        features: {
          localStorage: !!window.localStorage,
          sessionStorage: !!window.sessionStorage,
          indexedDB: !!window.indexedDB,
          fetch: !!window.fetch,
          promise: typeof Promise !== 'undefined',
          geolocation: !!navigator.geolocation,
          webgl: this.getWebGLFingerprint() !== '',
          webrtc: !!window.RTCPeerConnection || !!window.webkitRTCPeerConnection
        }
      };
      
      // 检查必需功能
      const requiredFeatures = ['localStorage', 'fetch', 'promise'];
      for (const feature of requiredFeatures) {
        if (!compatibility.features[feature]) {
          compatibility.isSupported = false;
          compatibility.reason = `Required feature not supported: ${feature}`;
          break;
        }
      }
      
      return compatibility;
    }

    checkPrivacyCompliance() {
      // GDPR 合规检查
      if (this.config.privacy.gdpr.enabled) {
        // 检查用户同意
        const consent = localStorage.getItem('xapptool_gdpr_consent');
        if (!consent) {
          throw new Error('GDPR consent required');
        }
      }
      
      // CCPA 合规检查
      if (this.config.privacy.ccpa.enabled) {
        const doNotSell = localStorage.getItem('xapptool_ccpa_do_not_sell');
        if (doNotSell === 'true') {
          throw new Error('CCPA do not sell preference set');
        }
      }
    }

    startCacheCleanup() {
      setInterval(() => {
        const now = Date.now();
        for (const [key, value] of this.cache.entries()) {
          if (value.expires <= now) {
            this.cache.delete(key);
          }
        }
      }, 60000); // 每分钟清理一次
    }

    startBatchProcessor() {
      setInterval(() => {
        if (this.requestQueue.length > 0) {
          const batch = this.requestQueue.splice(0, this.config.performance.batchSize);
          this.processBatchRequest(batch);
        }
      }, this.config.performance.batchInterval);
    }

    async processBatchRequest(requests) {
      try {
        const response = await this.request('/api/v1/batch', { requests });
        this.log('Batch request processed:', response);
      } catch (error) {
        this.log('Batch request failed:', error);
      }
    }

    // 版本信息
    getVersion() {
      return '1.0.0';
    }

    // 调试信息
    getDebugInfo() {
      return {
        version: this.getVersion(),
        isInitialized: this.isInitialized,
        deviceFingerprint: this.deviceFingerprint,
        sessionId: this.sessionId,
        config: this.config,
        cacheSize: this.cache.size,
        queueSize: this.requestQueue.length
      };
    }

    // 性能指标
    getPerformanceMetrics() {
      if (!window.performance) {
        return {};
      }
      
      const navigation = performance.getEntriesByType('navigation')[0];
      return {
        domContentLoaded: navigation.domContentLoadedEventEnd - navigation.domContentLoadedEventStart,
        loadComplete: navigation.loadEventEnd - navigation.loadEventStart,
        firstPaint: performance.getEntriesByType('paint')[0]?.startTime || 0,
        memory: performance.memory ? {
          used: performance.memory.usedJSHeapSize,
          total: performance.memory.totalJSHeapSize,
          limit: performance.memory.jsHeapSizeLimit
        } : null
      };
    }

    // 自动跳转逻辑：尝试打开App，失败则跳转应用市场或自定义地址
    async autoJump(options = {}) {
      const params = options.params || {}
      const platform = navigator.userAgent.toLowerCase().includes('iphone') || navigator.userAgent.toLowerCase().includes('ipad') ? 'ios'
        : navigator.userAgent.toLowerCase().includes('harmony') ? 'harmony'
        : 'android'

      const openScheme = (scheme) => {
        if (!scheme) return false
        const iframe = document.createElement('iframe')
        iframe.style.display = 'none'
        iframe.src = scheme
        document.body.appendChild(iframe)
        setTimeout(() => document.body.removeChild(iframe), 2000)
        return true
      }

      const redirect = (url) => {
        if (!url) return
        const qs = new URLSearchParams(params).toString()
        window.location.href = qs ? `${url}${url.includes('?') ? '&' : '?'}${qs}` : url
      }

      const start = Date.now()
      let triedOpen = false

      if (platform === 'ios') {
        triedOpen = openScheme(options.ios?.scheme)
        setTimeout(() => {
          const elapsed = Date.now() - start
          if (elapsed < 1500) {
            if (options.ios?.universal) redirect(options.ios.universal)
            else if (options.ios?.store) redirect(options.ios.store)
            else redirect(options.fallback)
          }
        }, 800)
      } else if (platform === 'android') {
        triedOpen = openScheme(options.android?.scheme)
        setTimeout(() => {
          const elapsed = Date.now() - start
          if (elapsed < 1500) {
            if (options.android?.store) redirect(options.android.store)
            else redirect(options.fallback)
          }
        }, 800)
      } else {
        if (options.harmony?.store) redirect(options.harmony.store)
        else redirect(options.fallback)
      }

      if (options.preferFallback) {
        redirect(options.fallback)
      }
    }

    // 生成分享落地页链接（自定义或统一）
    getShareUrl(config = {}, params = {}, type = 'auto') {
      const base = (type === 'custom' || config.is_custom_landing) ? `/lp/custom/${config.id}` : `/lp/${config.id}`
      const qs = new URLSearchParams(params).toString()
      return qs ? `${base}?${qs}` : base
    }

    // SHA-256 哈希
    sha256(str) {
      const utf8 = unescape(encodeURIComponent(str));
      const m = [];
      for (let i = 0; i < utf8.length; i++) m.push(utf8.charCodeAt(i));
      const l = m.length * 8;
      m.push(0x80);
      while ((m.length % 64) !== 56) m.push(0);
      for (let i = 7; i >= 0; i--) m.push((l >>> (i * 8)) & 0xff);
      const h = [0x6a09e667,0xbb67ae85,0x3c6ef372,0xa54ff53a,0x510e527f,0x9b05688c,0x1f83d9ab,0x5be0cd19];
      const k = [0x428a2f98,0x71374491,0xb5c0fbcf,0xe9b5dba5,0x3956c25b,0x59f111f1,0x923f82a4,0xab1c5ed5,0xd807aa98,0x12835b01,0x243185be,0x550c7dc3,0x72be5d74,0x80deb1fe,0x9bdc06a7,0xc19bf174,0xe49b69c1,0xefbe4786,0x0fc19dc6,0x240ca1cc,0x2de92c6f,0x4a7484aa,0x5cb0a9dc,0x76f988da,0x983e5152,0xa831c66d,0xb00327c8,0xbf597fc7,0xc6e00bf3,0xd5a79147,0x06ca6351,0x14292967,0x27b70a85,0x2e1b2138,0x4d2c6dfc,0x53380d13,0x650a7354,0x766a0abb,0x81c2c92e,0x92722c85,0xa2bfe8a1,0xa81a664b,0xc24b8b70,0xc76c51a3,0xd192e819,0xd6990624,0xf40e3585,0x106aa070,0x19a4c116,0x1e376c08,0x2748774c,0x34b0bcb5,0x391c0cb3,0x4ed8aa4a,0x5b9cca4f,0x682e6ff3,0x748f82ee,0x78a5636f,0x84c87814,0x8cc70208,0x90befffa,0xa4506ceb,0xbef9a3f7,0xc67178f2];
      for (let i = 0; i < m.length; i += 64) {
        const w = new Array(64);
        for (let j = 0; j < 16; j++) {
          w[j] = (m[i + j*4] << 24) | (m[i + j*4 +1] << 16) | (m[i + j*4 +2] << 8) | (m[i + j*4 +3]);
        }
        for (let j = 16; j < 64; j++) {
          const s0 = ((w[j-15] >>> 7) | (w[j-15] << 25)) ^ ((w[j-15] >>> 18) | (w[j-15] << 14)) ^ (w[j-15] >>> 3);
          const s1 = ((w[j-2] >>> 17) | (w[j-2] << 15)) ^ ((w[j-2] >>> 19) | (w[j-2] << 13)) ^ (w[j-2] >>> 10);
          w[j] = (w[j-16] + s0 + w[j-7] + s1) | 0;
        }
        let a=h[0],b=h[1],c=h[2],d=h[3],e=h[4],f=h[5],g=h[6],hh=h[7];
        for (let j = 0; j < 64; j++) {
          const S1 = ((e >>> 6) | (e << 26)) ^ ((e >>> 11) | (e << 21)) ^ ((e >>> 25) | (e << 7));
          const ch = (e & f) ^ ((~e) & g);
          const temp1 = (hh + S1 + ch + k[j] + w[j]) | 0;
          const S0 = ((a >>> 2) | (a << 30)) ^ ((a >>> 13) | (a << 19)) ^ ((a >>> 22) | (a << 10));
          const maj = (a & b) ^ (a & c) ^ (b & c);
          const temp2 = (S0 + maj) | 0;
          hh = g; g = f; f = e; e = (d + temp1) | 0; d = c; c = b; b = a; a = (temp1 + temp2) | 0;
        }
        h[0]=(h[0]+a)|0; h[1]=(h[1]+b)|0; h[2]=(h[2]+c)|0; h[3]=(h[3]+d)|0; h[4]=(h[4]+e)|0; h[5]=(h[5]+f)|0; h[6]=(h[6]+g)|0; h[7]=(h[7]+hh)|0;
      }
      let out='';
      for (let i = 0; i < h.length; i++) {
        out += ('00000000' + (h[i] >>> 0).toString(16)).slice(-8);
      }
      return out;
    }
  }

  // 暴露到全局
  global.XappTool = XappTool;
  
  // AMD 支持
  if (typeof define === 'function' && define.amd) {
    define(function() {
      return XappTool;
    });
  }
  
  // CommonJS 支持
  if (typeof module !== 'undefined' && module.exports) {
    module.exports = XappTool;
  }

})(typeof window !== 'undefined' ? window : this);